/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package im.filters;

import im.eventpackage.*;
import im.eventpackage.*;
import java.util.StringTokenizer;
import java.util.Vector;
import im.subscriptionpackage.*;

/**
 *
 * @author Giovanni 
 */
public class ContentEventFilter {

    public ContentEventFilter() {
    }

    Vector predicateParser(String phrase){

         StringTokenizer st = new StringTokenizer(phrase);
        String name = null;
        Object value = null;
        String compare =null;
                Vector pairCont = new Vector();


        /*while (st.hasMoreTokens()) {

        String str = st.nextToken();

        if (str.equals("name") || str.equals("value")) {
        name = str;
        } else if (str.equals("<") || str.equals(">") || str.equals("==") || str.equals("<=") || str.equals(">=")) {
        compare=str;
        } else if (!str.equals("and")&&!str.equals("or")){
        value = str;
        }

        if (name != null && value != null && compare!=null) {
        Predicate p = new Predicate(null, null, null);
        p.setName(name);
        p.setCompare(compare);
        p.setValue(value);
        // System.out.println("inseriamo: " + p.getName() + " " + p.getCompare()+" "+p.getValue());
        pairCont.add(p);
        name = null;
        compare = null;
        value = null;

        }*/
        do {
            name = st.nextToken();
            compare = st.nextToken();
            value = st.nextToken();
            
            pairCont.add(new Predicate(name, compare, value));
        } while(st.hasMoreElements() && st.nextElement()!=null);

        return pairCont;
    }

    Vector booleanParser(String phrase) {

        Vector booleanCont = new Vector();
        int bool = 0; //1:and 2:or
        StringTokenizer st = new StringTokenizer(phrase);
        while (st.hasMoreTokens()) {
            String str = st.nextToken();

            if (str.equals("and")) {
                bool = 1;
                booleanCont.add(bool);
            } else if (str.equals("or")) {
                bool = 2;
                booleanCont.add(bool);
            }
        }

        return booleanCont;
    }



        public boolean filterSubscription(Event ev, ContentSubscription sub) {

        if(sub==null)
            return true;

        boolean ret = false;

        //parsiamo sottoscrizione
        //System.out.println("parso sub");
        Vector pairFromSubscription=predicateParser(sub.getCriteria());
        Vector booleanFromSubscription=booleanParser(sub.getCriteria());

        //parsiamo evento.content
        //System.out.println("parso evento");
        Vector pairFromEvent=predicateParser(ev.getContent());
        //Vector booleanFromEvent=booleanParser(ev.getContent());

        int size = pairFromSubscription.size();
        int sizePairOfEvents= pairFromEvent.size();

        //boolean m = false;
        boolean boolRes[];
        boolRes = new boolean[size];

        for (int i = 0; i < size; i++) {

            Predicate p1 = (Predicate) pairFromSubscription.get(i);
            boolRes[i] = false;

            for (int j = 0; j < sizePairOfEvents; j++) {

                Predicate p2 = (Predicate) pairFromEvent.get(j);
                //caso ==

                    if (p1.getCompare().toString().equals("==") && p1.getName().toString().equals(p2.getName().toString()) && p1.getCompare().toString().equals(p2.getCompare().toString()) && p1.getValue().toString().equals(p2.getValue().toString())) {
                        //System.out.println("p1.name:" + p1.getName().toString() + " " + "p2.name:" + p2.getName().toString());
                        //System.out.println("p1.compare:" + p1.getCompare().toString() + " " + "p2.compare:" + p2.getCompare().toString());
                        //System.out.println("p1.value:" + p1.getValue().toString() + " " + "p2.value:" + p2.getValue().toString());

                        boolRes[i] = true;
                      //  System.out.println("boolRes[" + i + "]: " + boolRes[i]);
                        
                    } 
                
                //caso <

                    if (p1.getCompare().toString().equals("<") && p1.getName().toString().equals(p2.getName().toString()) && (Integer.parseInt(p1.getValue().toString()) > Integer.parseInt(p2.getValue().toString()))) {

                        //System.out.println("p1.name:" + p1.getName().toString() + " " + "p2.name:" + p2.getName().toString());
                        //System.out.println("p1.compare:" + p1.getCompare().toString() + " " + "p2.compare:" + p2.getCompare().toString());
                        //System.out.println("p1.value:" + p1.getValue().toString() + " " + "p2.value:" + p2.getValue().toString());

                        boolRes[i] = true;
                       // System.out.println("boolRes[" + i + "]: " + boolRes[i]);
                        
                    } 
                
                //caso >
               

                    if (p1.getCompare().toString().equals(">") && p1.getName().toString().equals(p2.getName().toString()) && (Integer.parseInt(p1.getValue().toString()) < Integer.parseInt(p2.getValue().toString()))) {

                        //System.out.println("p1.name:" + p1.getName().toString() + " " + "p2.name:" + p2.getName().toString());
                        //System.out.println("p1.compare:" + p1.getCompare().toString() + " " + "p2.compare:" + p2.getCompare().toString());
                        //System.out.println("p1.value:" + p1.getValue().toString() + " " + "p2.value:" + p2.getValue().toString());

                        boolRes[i] = true;
                      //  System.out.println("boolRes[" + i + "]: " + boolRes[i]);
                       
                    } 

                //caso <=

                    if (p1.getCompare().toString().equals("<=") && p1.getName().toString().equals(p2.getName().toString()) && (Integer.parseInt(p1.getValue().toString()) >= Integer.parseInt(p2.getValue().toString()))) {

                        //System.out.println("p1.name:" + p1.getName().toString() + " " + "p2.name:" + p2.getName().toString());
                        //System.out.println("p1.compare:" + p1.getCompare().toString() + " " + "p2.compare:" + p2.getCompare().toString());
                        //System.out.println("p1.value:" + p1.getValue().toString() + " " + "p2.value:" + p2.getValue().toString());

                        boolRes[i] = true;
                       // System.out.println("boolRes[" + i + "]: " + boolRes[i]);
                       
                    } 
                
                //caso >=

                    if (p1.getCompare().toString().equals(">=") && p1.getName().toString().equals(p2.getName().toString()) && (Integer.parseInt(p1.getValue().toString()) <= Integer.parseInt(p2.getValue().toString()))) {

                        //System.out.println("p1.name:" + p1.getName().toString() + " " + "p2.name:" + p2.getName().toString());
                        //System.out.println("p1.compare:" + p1.getCompare().toString() + " " + "p2.compare:" + p2.getCompare().toString());
                        //System.out.println("p1.value:" + p1.getValue().toString() + " " + "p2.value:" + p2.getValue().toString());

                        boolRes[i] = true;
                       // System.out.println("boolRes[" + i + "]: " + boolRes[i]);
                       
                    } 

            }

            //boolRes[i] = m;
           // System.out.println("2: boolRes[" + i + "]: " + boolRes[i]);

        }

        //operazione booleana predicati

        if (pairFromSubscription.size() == 1) {

            ret = boolRes[0];

        } else {
            boolean f = true;
            for (int j = 0; j < size; j++) {

                if (j > 0) {

                    int v = Integer.parseInt(booleanFromSubscription.get(j - 1).toString());
                    if (v == 1) {
                        f = boolRes[j] && f;
                    }
                    if (v == 2) {
                        f = boolRes[j] || f;
                    }
                } else {
                    f = boolRes[j];
                }
            }
            ret = f;

        }
        return ret;

    }
}